<?php
declare(strict_types=1);

namespace think\admin\test\service;

use think\admin\Service;
use think\admin\test\repository\PaymentRepository;
use think\admin\test\repository\UserRepository;
use think\admin\exception\BusinessException;

class PaymentService extends Service
{
    /**
     * 仓储类型定义
     */
    public const REPOSITORY_PAYMENT = 'payment';
    public const REPOSITORY_USER = 'user';

    /**
     * 支付状态定义
     */
    public const STATUS_PENDING = 1;    // 待支付
    public const STATUS_SUCCESS = 2;    // 支付成功
    public const STATUS_FAILED = 3;     // 支付失败
    public const STATUS_REFUNDED = 4;   // 已退款

    /**
     * 初始化
     * @throws BusinessException
     */
    protected function initialize(): void
    {
        // 设置支付主仓储
        $this->repository = new PaymentRepository($this->app);
        
        // 注册用户仓储
        $this->registerRepository(self::REPOSITORY_USER, new UserRepository($this->app));
    }

    /**
     * 创建支付记录
     * @param array $data
     * @return array
     * @throws BusinessException
     */
    public function create(array $data): array
    {
        // 验证必要参数
        if (empty($data['user_id']) || empty($data['amount']) || empty($data['order_id'])) {
            throw new BusinessException('参数错误');
        }

        // 检查用户
        $userRepo = $this->getRepository(self::REPOSITORY_USER);
        $user = $userRepo->detail($data['user_id']);
        if (empty($user)) {
            throw new BusinessException('用户不存在');
        }

        // 创建支付记录
        $paymentData = [
            'user_id' => $data['user_id'],
            'order_id' => $data['order_id'],
            'amount' => $data['amount'],
            'status' => self::STATUS_PENDING,
            'payment_method' => $data['payment_method'] ?? 'balance',
            'created_at' => date('Y-m-d H:i:s')
        ];

        if (!$this->repository->create($paymentData)) {
            throw new BusinessException('创建支付记录失败');
        }

        return $paymentData;
    }

    /**
     * 执行支付
     * @param int $paymentId 支付记录ID
     * @return bool
     * @throws BusinessException
     */
    public function pay(int $paymentId): bool
    {
        return $this->transaction(function() use ($paymentId) {
            // 获取支付记录
            $payment = $this->repository->detail($paymentId);
            if (empty($payment)) {
                throw new BusinessException('支付记录不存在');
            }

            if ($payment['status'] !== self::STATUS_PENDING) {
                throw new BusinessException('支付状态异常');
            }

            // 获取用户信息
            $userRepo = $this->getRepository(self::REPOSITORY_USER);
            $user = $userRepo->detail($payment['user_id']);
            if (empty($user)) {
                throw new BusinessException('用户不存在');
            }

            // 检查余额
            if ($user['balance'] < $payment['amount']) {
                // 更新支付状态为失败
                $this->repository->update($paymentId, [
                    'status' => self::STATUS_FAILED,
                    'error_message' => '余额不足',
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
                throw new BusinessException('用户余额不足');
            }

            // 扣减余额
            if (!$userRepo->decreaseBalance($payment['user_id'], $payment['amount'])) {
                // 更新支付状态为失败
                $this->repository->update($paymentId, [
                    'status' => self::STATUS_FAILED,
                    'error_message' => '余额扣减失败',
                    'updated_at' => date('Y-m-d H:i:s')
                ]);
                throw new BusinessException('余额扣减失败');
            }

            // 更新支付状态为成功
            return $this->repository->update($paymentId, [
                'status' => self::STATUS_SUCCESS,
                'paid_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        });
    }

    /**
     * 退款
     * @param int $paymentId 支付记录ID
     * @return bool
     * @throws BusinessException
     */
    public function refund(int $paymentId): bool
    {
        return $this->transaction(function() use ($paymentId) {
            // 获取支付记录
            $payment = $this->repository->detail($paymentId);
            if (empty($payment)) {
                throw new BusinessException('支付记录不存在');
            }

            if ($payment['status'] !== self::STATUS_SUCCESS) {
                throw new BusinessException('支付状态异常');
            }

            // 获取用户信息
            $userRepo = $this->getRepository(self::REPOSITORY_USER);
            $user = $userRepo->detail($payment['user_id']);
            if (empty($user)) {
                throw new BusinessException('用户不存在');
            }

            // 退还余额
            if (!$userRepo->increaseBalance($payment['user_id'], $payment['amount'])) {
                throw new BusinessException('余额退还失败');
            }

            // 更新支付状态为已退款
            return $this->repository->update($paymentId, [
                'status' => self::STATUS_REFUNDED,
                'refunded_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        });
    }
} 